/*--------------------------------------------------------------------------------------*\
**
** thieves_guild_window.cpp
**
** Heroes IV
** Copyright 2001, The 3DO Company
**
\*--------------------------------------------------------------------------------------*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "thieves_guild_window.h"

#include "adventure_map.h"
#include "bitmap_group_cache.h"
#include "bitmap_layer_cache_window.h"
#include "bound_handler.h"
#include "button.h"
#include "button_cache.h"
#include "external_string.h"
#include "format_string.h"
#include "interface_help.h"
#include "item_help_block.h"
#include "material_array.h"
#include "material_names.h"
#include "player.h"
#include "standard_fonts.h"
#include "text_window.h"
#include "town.h"

extern t_button_cache g_ok_button;

namespace 
{ // unnamed namespace

    t_bitmap_group_cache        k_thieves_guild_bitmaps ("dialog.thieves_guild");
    
    t_external_string const k_text_title ( "thieves_guild_title.misc" );
    t_external_string const k_text_intro ( "thieves_guild_intro.misc" );
    t_external_string const k_text_towns ( "thieves_guild_towns.misc" );
    t_external_string const k_text_armies ( "thieves_guild_armies.misc" );
    t_external_string const k_text_income ( "thieves_guild_income.misc" );
}

static int get_player_total_gold_income ( t_player* player_ptr, t_adventure_map &map )
{
    int i;
    int total_gold = 0;
	int	day = map.get_day();

	t_material_array const& player_income_array = player_ptr->get_income( day );
    
	for (i = 0; i < k_material_count; i++)
    {
        total_gold += ( player_income_array[i] / k_material_value[i] );
    }

    return (total_gold);
}

// Set clipper bar. - (from army_list_window)
static void set_bar_height( int value, int max_value, int bar_height, t_window* clipper, t_window* background,
                int height_offset, int min_value )
{
	int maximum			= bar_height;
	int height			= value * maximum / max_value;
	t_screen_rect rect	= clipper->get_screen_rect();

	if (height > maximum)
		height = maximum;
    
    if (height < min_value)
        height = min_value;
    
    height += height_offset;

	rect.top = rect.bottom - height;
	clipper->move_screen_rect( rect, false );
}

t_thieves_guild_window::t_thieves_guild_window( t_window* parent, t_adventure_map &map )
                   : t_window( k_completely_transparent, parent )
{
	t_help_block const&		help = get_help_block( "thieves_guild" );

	m_bitmaps_ptr = k_thieves_guild_bitmaps.get();
	
	t_screen_rect rect;

	/*
    ** Create background bitmap.
    */
	t_bitmap_layer const*   layer;
	t_window*               background;
	t_screen_point          origin(0,0);

	layer = m_bitmaps_ptr->find( "background" );
	background = new t_bitmap_layer_window( layer, origin, this );

    // Set position.
	t_screen_rect parent_rect;
    parent_rect = get_parent()->get_client_rect();
	rect = m_bitmaps_ptr->get_rect();
	rect += (parent_rect.size() - rect.size()) / 2;
	init( rect );

	// Add buttons.
	t_button* button_ptr;

    rect = m_bitmaps_ptr->find( "ok_button" )->get_rect();
	button_ptr = new t_button( g_ok_button.get(), rect.top_left(), this );
	button_ptr->set_click_handler( bound_handler( *this, &t_thieves_guild_window::ok_clicked ));
  set_help( button_ptr, help, "ok" );	

    // Text windows.
    t_text_window*  text_window_ptr;

	rect = m_bitmaps_ptr->find( "title" )->get_rect();
	text_window_ptr  = new t_text_window( get_font( rect.height() ), rect, this, "", t_pixel_24(0,0,0) );
    text_window_ptr->set_text ( k_text_title );
	text_window_ptr->set_center_horizontal();

	rect = m_bitmaps_ptr->find( "text" )->get_rect();
	text_window_ptr  = new t_text_window( get_font( 18 ), rect, this, "", t_pixel_24(0,0,0) );
    text_window_ptr->set_text ( k_text_intro );
	text_window_ptr->set_center_horizontal();

    rect = m_bitmaps_ptr->find( "town_text" )->get_rect();
    text_window_ptr = new t_text_window( get_font( rect.height() ), rect, this, "", t_pixel_24( 0,0,0 ) );
    text_window_ptr->set_text ( k_text_towns ); //format_string("%s", help.get_help("towns") ) );
	text_window_ptr->set_center_horizontal();

    rect = m_bitmaps_ptr->find( "army_text" )->get_rect();
    text_window_ptr = new t_text_window( get_font( rect.height() ), rect, this, "", t_pixel_24( 0,0,0 ) );
    text_window_ptr->set_text ( k_text_armies ); //format_string("%s", help.get_help("armies") ) );
	text_window_ptr->set_center_horizontal();

    rect = m_bitmaps_ptr->find( "income_text" )->get_rect();
    text_window_ptr = new t_text_window( get_font( rect.height() ), rect, this, "", t_pixel_24( 0,0,0 ) );
    text_window_ptr->set_text ( k_text_income ); //format_string("%s", help.get_help("gold") ) );
	text_window_ptr->set_center_horizontal();

    show_town_bars( map );
    show_army_bars( map );
    show_income_bars( map );
}

void t_thieves_guild_window::draw_bar( t_window* parent_ptr, t_screen_point origin,
                int number, int max_number, t_player_color player_color )
{
    t_screen_rect           rect;
	t_window*               clipper_ptr;
	t_window*               background_ptr;
	t_window*               window_ptr;
    t_bitmap_layer const*   black_outline = m_bitmaps_ptr->find( "black_outline" );
    t_screen_point          black_offset;
    t_bitmap_layer const*   gold_border = m_bitmaps_ptr->find( "gold_border" );
    t_screen_point          gold_offset;
    t_bitmap_layer const*   inner_outline = m_bitmaps_ptr->find( "inner_outline" );
    t_screen_point          inner_offset;
	std::string             bar_name;
	int                     bar_height;
    
    bar_name = format_string( "%s_bar", k_player_color_keyword[ player_color ] );
	t_bitmap_layer const* player_bar = m_bitmaps_ptr->find( bar_name );
    /*
    ** Get player's color bar height - use this height for all layers 
    ** for consistency.
    */
    bar_height = player_bar->get_rect().height();

    black_offset = black_outline->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();
    gold_offset = gold_border->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();
    inner_offset = inner_outline->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();
    
    // Black outline.
    rect = black_outline->get_rect();
    background_ptr = new t_window( rect - rect.top_left() + origin + black_offset, k_some_transparency, parent_ptr );
    clipper_ptr = new t_window( rect - rect.top_left(), k_completely_transparent,
	                                  background_ptr );
    window_ptr = new t_bitmap_layer_window( black_outline, t_screen_point(0,0), clipper_ptr, false );
    set_bar_height( number, max_number, bar_height, clipper_ptr,
	            background_ptr, 8, 1 );
        
    // Gold border.
    rect = gold_border->get_rect();
	background_ptr = new t_window( rect - rect.top_left() + origin + gold_offset, k_some_transparency, parent_ptr );
	clipper_ptr = new t_window( rect - rect.top_left(), k_completely_transparent,
	                                  background_ptr );
    window_ptr = new t_bitmap_layer_window( gold_border, t_screen_point(0,0), clipper_ptr, false );
    set_bar_height( number, max_number, bar_height, clipper_ptr,
	            background_ptr, 6, 1 );

    // Inner border.
    rect = inner_outline->get_rect();
	background_ptr = new t_window( rect - rect.top_left() + origin + inner_offset, k_some_transparency, parent_ptr );
	clipper_ptr = new t_window( rect - rect.top_left(), k_completely_transparent,
	                                  background_ptr );
    window_ptr = new t_bitmap_layer_window( inner_outline, t_screen_point(0,0), clipper_ptr, false );
    set_bar_height( number, max_number, bar_height, clipper_ptr,
	            background_ptr, 2, 1 );

    // Player color bar.
	rect = player_bar->get_rect();
	background_ptr = new t_window( rect - rect.top_left() + origin, k_some_transparency, parent_ptr );
	clipper_ptr = new t_window( rect - rect.top_left(), k_completely_transparent,
	                                  background_ptr );
    window_ptr = new t_bitmap_layer_window( player_bar, t_screen_point(0,0), clipper_ptr, false );
    set_bar_height( number, max_number, bar_height, clipper_ptr,
	            background_ptr, 0, 1 );
}

void t_thieves_guild_window::show_town_bars( t_adventure_map &map )
{
    int i;
	t_player_list const& players = map.get_players();
    int max_towns = map.get_town_count();
    int num_players = players.size();

    // No towns?
    if (max_towns == 0)
        return;

	t_screen_point          point( 0, 0 );
	t_screen_point          offset( 0, 0 );
	t_screen_point          bar_offset( 0, 0 );
	std::string             bar_name;
    int                     bar_width = m_bitmaps_ptr->find( "red_bar" )->get_rect().width();
    t_screen_rect           rect;

    offset = m_bitmaps_ptr->find( "town_graph" )->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();
    bar_offset = m_bitmaps_ptr->find( "green_bar" )->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();
    
    rect = m_bitmaps_ptr->find( "town_graph" )->get_rect();

    point = rect.top_left();
    point.x += ((rect.width()/2) - ( ((bar_offset.x * (num_players-1)) + bar_width) /2));
    point.y += -offset.y;

    for (i=0; i<num_players; i++)
    {
	    t_town_list* towns = players[i]->get_towns();
        int number_of_towns = players[i]->get_town_count();
	    t_player_color player_color = players[i]->get_color();
        bar_name = format_string( "%s_bar", k_player_color_keyword[ player_color ] );
	    t_bitmap_layer const* player_bar = m_bitmaps_ptr->find( bar_name );

        draw_bar( this, point, number_of_towns, max_towns, player_color );

        point.x += bar_offset.x;
    }
}

void t_thieves_guild_window::show_income_bars( t_adventure_map &map )
{
    int i;
	t_player_list const& players = map.get_players();
    int num_players = players.size();
    int map_income = map.get_total_income();

    if (map_income == 0)
        return;

	t_screen_point          point;
	t_screen_point          offset( 0, 0 );
	t_screen_point          bar_offset( 0, 0 );
	std::string             bar_name;
    int                     bar_width = m_bitmaps_ptr->find( "red_bar" )->get_rect().width();
    t_screen_rect           rect;

    offset = m_bitmaps_ptr->find( "town_graph" )->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();
    bar_offset = m_bitmaps_ptr->find( "green_bar" )->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();
    
    rect = m_bitmaps_ptr->find( "income_graph" )->get_rect();

    point = rect.top_left();
    point.x += ((rect.width()/2) - ( ((bar_offset.x * (num_players-1)) + bar_width) /2));
    point.y += -offset.y;

    for (i=0; i<num_players; i++)
    {
	    t_player_color player_color = players[i]->get_color();
        bar_name = format_string( "%s_bar", k_player_color_keyword[ player_color ] );
	    t_bitmap_layer const* player_bar = m_bitmaps_ptr->find( bar_name );

        int player_income = get_player_total_gold_income ( &(*players[i]), map );
        
        draw_bar( this, point, player_income, map_income, player_color );
        point.x += bar_offset.x;
    }
}

void t_thieves_guild_window::show_army_bars( t_adventure_map &map )
{
    int i;
	t_player_list const& players = map.get_players();
    int num_players = players.size();

	t_screen_point          point;
	t_screen_point          offset( 0, 0 );
	t_screen_point          bar_offset( 0, 0 );
	std::string             bar_name;
    int                     bar_width = m_bitmaps_ptr->find( "red_bar" )->get_rect().width();
    t_screen_rect           rect;

    offset = m_bitmaps_ptr->find( "town_graph" )->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();

    // Figure out width used by one bar.
    bar_offset = m_bitmaps_ptr->find( "green_bar" )->get_rect().top_left() - m_bitmaps_ptr->find( "red_bar" )->get_rect().top_left();

    rect = m_bitmaps_ptr->find( "army_graph" )->get_rect();

    // Figure out starting point for bars.
    point = rect.top_left();
    point.x += ((rect.width()/2) - ( ((bar_offset.x * (num_players-1)) + bar_width) /2));
    point.y += -offset.y;

    // Get max experience.
    int max_experience = 6000;
    for (i=0; i<num_players; i++)
    {
        int player_experience = players[i]->get_total_army_experience();
        if (player_experience > max_experience)
            max_experience = player_experience;
    }

    for (i=0; i<num_players; i++)
    {
	    t_player_color player_color = players[i]->get_color();
        bar_name = format_string( "%s_bar", k_player_color_keyword[ player_color ] );
	    t_bitmap_layer const* player_bar = m_bitmaps_ptr->find( bar_name );

        int player_experience = players[i]->get_total_army_experience();
        
        draw_bar( this, point, player_experience, max_experience, player_color );
        point.x += bar_offset.x;
    }
}

void t_thieves_guild_window::ok_clicked( t_button* button_ptr )
{
    close();    
}

